/*************
author:: libo
license:: MIT
*****************/

//一些小算法
#ifndef LIBCELL_TOOLS_ALGORITHM_H_
#define LIBCELL_TOOLS_ALGORITHM_H_

#include "tools_vector.h"
#include<Mesh/_Func_.h>
#include<math.h>
#include <tool/libcell_tools_octree.h>
#define quote lib_cell_quote

#ifdef __cplusplus
extern "C" {

#endif
static inline Vertex transfer_point2vertex(double* p,int size)
{
    Vertex re;
    Vertex_init_(&re);
    re.point=p;re.point_size=size;
    return re;

}

double* mesh_compute_bounding_box_from_node(Node* n);
//
// 这应该返回n维的box
//
double* mesh_compute_bounding_box(Mesh* m);
//把mesh或者点云调整到[-1,1]的立方体里
void mesh_adjust_mesh_to_unit_hexahedron(Mesh* mesh,double*box);
//调整c的halffaces顺序，任意维流形有效
//非单形也有效
//因为c的halffacess的顺序默认并不规则
//
Node* Mesh_adjust_halffaces(template_c* c);

//调整cell点的顺序,二维流形有效

template_v** mesh_adjust_vertices(Mesh*m,template_c*c);


//交叉曲线也有效
// 任意维流形有效
//非单形也有效
//tree储存新建的cell到被删的cell->id的映射
//tree1储存新建点到旧点的映射
//需要修改的地方: 需要储存新建点到旧点的映射

//int_rb_tree_free_value(tree);int_rb_tree_free(tree);
//int_rb_tree_free(tree1);
//the face doesn't need to be arranged in order

// 判断切割点，根据该点的联通区域个数
// 比如给定一些faces集合，并以此作为墙，对每个点进行联通区域计算，每个联通区域创建一个点
//
void  Mesh_cut_along_the_curvef(Mesh* m,Node* faces,Int_RB_Tree*tree,Int_RB_Tree*tree1);


// tree储存新建的cell到被删的cell的映射
// tree1储存新建点到旧点的映射
// the vertices need arranged in order
// void Mesh_cut_along_the_curvev(Mesh* m,Node* vertices,Int_RB_Tree* tree,Int_RB_Tree*tree1);

Node* split_unicom_region_from_sub_node( Node* node );


Node* split_unicom_region_from_sub_vector( LB_Vector1_voidptr vec );

//分割连通区域
//对任意维流形都有效
Node* split_unicom_region( Int_RB_Tree* tree_c);

// 分割连通区域,返回mesh
// 对任意维流形都有效

Node* split_unicom_region2mesh(Mesh *m );

Node* get_shortest_path(Mesh* m, template_v* v1,template_v*v2);

double compute_surface_area(Mesh *m);

Node* create_surface_uniform_sampling_points(Mesh* m,int num,double dense);

int oc_node_divide_one_leaf_on_cells(OC_Node* ocn);


/*
* @brief 新版本的缝合边界，会对边界进行重采样，算法内部原理会重采样，不对原数据修改
* vb1和vb2会按照顺序进行缝合，所以要注意vb1和vb2的顺序。
* 一般创建的三角形第一个点是vb1的点，第二个点是vb2的点,不管第三个点的顺序如何。那么三角形的半边
* 方向和vb1顺序相反。
*
* @param sampling_dis :采样距离
* @param is_loop： vb1和vb2 是否构成loop
*
*
*/
Node* libcell_tools_suture_two_boundarriesn(Node* vb1,
    Node* vb2,int is_loop,double sampling_dis);



//
// Node* libcell_tools_suture_two_boundarries(Node* vb1,
//     Node* vb2,int is_loop);
//
// 二维流形边界的简化
//@param vertex_is_delete:额外要删除的点
//
Mesh* mesh_simplyfied_mesh_boundires(Mesh* m,double threshold,
    int (*vertex_is_delete)(template_v*),
    template_v** vs,int len);

/*
 * @brief ://swap_edge
 //任意维有效
 //单形有效
 //要判断是否符合交换条件
 // 返回新建的cells
 */

Node* swap_face(Mesh* m,template_f* f);
//任意维有效
// 对边界face也有效
template_v* collapse_edge(Mesh* m,template_f* f ,double* p);

template_v* collapse_edgen(Mesh* m,template_f* f ,double* p,double* normal);

// 细分boundary，为了防止边界有一个点，这个点链接的两条边界edge都属于同一个三角形
// 这个函数可以推广到高维
//
void libcell_tools_xifen_mesh_boundary(Mesh* m);

//
//
//
/* @brief 通过swap face来调整折叠cell
 * @param threshold : 判断折叠的阙值，一般负数，-0.7 到 -1.0
 *
 */

void  adjust_fold_cells_swap_face(Mesh*m,double threshold);


// 只适用于单形网格
//
int is_cells_simple_connected_on_surface(Mesh* m,Int_RB_Tree* cells);


#undef quote
#ifdef __cplusplus
}
#endif

#endif
